<?php

namespace Gql\Core;

class With
{
    /**
     * 查询字段类型名
     * @var string
     */
    public $fieldName;

    /**
     * 关联模型函数名
     * @var string
     */
    public $withName;

    /**
     * 用户查询的关联模型的字段
     * @var array
     */
    public $fields = [];

    /**
     * 该关联模型的所有字段
     * @var array
     */
    public $fieldNodes = [];

    public function __construct(string $fieldName)
    {
        $this->fieldName = $fieldName;
    }

    public function setWithName(string $withName)
    {
        $this->withName = $withName;
    }

    public function getName()
    {
        return $this->withName ?? $this->fieldName;
    }

    /**
     * 该方法应该在 setFields 方法之前调用
     * @param array $fieldNodes
     */
    public function setFieldNodes(array $fieldNodes)
    {
        $this->fieldNodes = $fieldNodes;
    }

    /**
     * 该方法应该在 setFieldNodes 方法之后调用
     * @param array $fields
     */
    public function setFields(array $fields)
    {
        $fieldNodes = $this->fieldNodes;
        $this->fields = array_filter($fields, function ($item) use ($fieldNodes) {
            return in_array($item, $fieldNodes);
        });
    }

    public function pushField(string $fieldName)
    {
        array_push($this->fields, $fieldName);
    }

    public static function parse(Context $context, $callback = null)
    {
        $res=[];
        $withs = $context->withs;
        foreach ($withs as $key => $item){
            $key = $item->getName();
            $res[$key]=function ($query) use ($item, $key, $callback) {
                if (is_callable($callback)) {
                    call_user_func($callback, $query, $key, $item);
                } elseif (is_array($callback) || is_string($callback)) {
                    $query->addSelect($callback);
                }
                $query->addSelect($item->fields);
            };
        }
        return $res;
    }
}